xlv.obj.richEditor={
	extend:function(){
	},
	implement:function(){
		this.implement('xlv.imp.mvc');
		this.implement('xlv.imp.editor');		
	},
	pub:{
		defaultStyle:{fontFamily:'Arial',fontSize:'12px',backgroundColor:'#FFFFFF',margin:'8px'},
		paneSelectFont:'/xlive/toolPanes/editor/selectFont.html',
		paneSelectSize:'/xlive/toolPanes/editor/selectSize.html',
		paneSelectHead:'/xlive/toolPanes/editor/selectHead.html',
		paneSelectForeColor:'/xlive/toolPanes/editor/selectColor.html',
		paneSelectBackColor:'/xlive/toolPanes/editor/selectColor.html',
		paneInsertImage:'/xlive/toolPanes/editor/insertImage.html',
		paneInsertLink:'/xlive/toolPanes/editor/insertLink.html',
		paneInsertTable:'/xlive/toolPanes/editor/insertTable.html',
		paneContextMenu:'/xlive/toolPanes/editor/contextMenu.html',
		tool:[{id:'xlvid_richeditor_seperator2',title:'',cmd:''},
		       {id:'xlvid_richeditor_font',title:'font',cmd:'FontName'},
		       {id:'xlvid_richeditor_fontsize',title:'fontsize',cmd:'FontSize'},
		       {id:'xlvid_richeditor_headings',title:'headings',cmd:'FormatBlock'},
		       {id:'xlvid_richeditor_bold',title:'bold',cmd:'Bold'},
		       {id:'xlvid_richeditor_italic',title:'italic',cmd:'Italic'},
		       {id:'xlvid_richeditor_underline',title:'underline',cmd:'Underline'},
		       {id:'xlvid_richeditor_strikethrough',title:'strikethrough',cmd:'Strikethrough'},
		       {id:'xlvid_richeditor_seperator',title:'',cmd:''},
		       {id:'xlvid_richeditor_forecolor',title:'forecolor',cmd:'ForeColor'},
		       {id:'xlvid_richeditor_backcolor',title:'backcolor',cmd:'BackColor'},
		       {id:'xlvid_richeditor_seperator',title:'',cmd:''},
		       {id:'xlvid_richeditor_justifyfull',title:'justifyfull',cmd:'Justifyfull'},
		       {id:'xlvid_richeditor_justifyleft',title:'justifyleft',cmd:'Justifyleft'},
		       {id:'xlvid_richeditor_justifycenter',title:'justifycenter',cmd:'Justifycenter'},
		       {id:'xlvid_richeditor_justifyright',title:'justifyright',cmd:'Justifyright'},
		       {id:'xlvid_richeditor_seperator',title:'',cmd:''},
		       {id:'xlvid_richeditor_unorderedlist',title:'unorderedlist',cmd:'InsertUnorderedList'},
		       {id:'xlvid_richeditor_orderedlist',title:'orderedlist',cmd:'InsertOrderedList'},
		       {id:'xlvid_richeditor_outdent',title:'outdent',cmd:'Outdent'},
		       {id:'xlvid_richeditor_indent',title:'indent',cmd:'Indent'}],
		tool2:[
		       {id:'xlvid_richeditor_seperator2',title:'',cmd:''},
		       {id:'xlvid_richeditor_save',title:'save',cmd:'Save'},
		       {id:'xlvid_richeditor_seperator',title:'',cmd:''},
		       {id:'xlvid_richeditor_subscript',title:'subscript',cmd:'Subscript'},
		       {id:'xlvid_richeditor_superscript',title:'superscript',cmd:'Superscript'},
		       {id:'xlvid_richeditor_cut',title:'cut',cmd:'Cut'},
		       {id:'xlvid_richeditor_copy',title:'copy',cmd:'Copy'},
		       {id:'xlvid_richeditor_paste',title:'paste',cmd:'Paste'},
		       {id:'xlvid_richeditor_removeformat',title:'removeformat',cmd:''},
		       {id:'xlvid_richeditor_seperator',title:'',cmd:''},
		       {id:'xlvid_richeditor_undo',title:'undo',cmd:'Undo'},
		       {id:'xlvid_richeditor_redo',title:'redo',cmd:'Redo'},
		       {id:'xlvid_richeditor_seperator',title:'',cmd:''},
		       //{id:'xlvid_richeditor_inserttable',title:'inserttable',cmd:'InsertTable'},
		       {id:'xlvid_richeditor_insertimage',title:'insertimage',cmd:'InsertImage'},
		       {id:'xlvid_richeditor_insertlink',title:'insertlink',cmd:'InsertLink'},
		       {id:'xlvid_richeditor_seperator',title:'',cmd:''},
		       //{id:'xlvid_richeditor_preview',title:'preview',cmd:'Preview'},
		       {id:'xlvid_richeditor_viewSource',title:'viewSource',cmd:'ViewMode'},
		       {id:'xlvid_richeditor_print',title:'print',cmd:'Print'}]
	},
	create:function(tag){
		var div=document.createElement((tag||'div'));
		div.setAttribute('xlvobject','xlv.obj.richEditor');
		return div;			
	},
	properties:{
		defaultStyle:null,
		paneSelectFont:null,
		paneSelectSize:null,
		paneSelectHead:null,
		paneSelectForeColor:null,
		paneSelectBackColor:null,
		paneInsertImage:null,
		paneInsertLink:null,
		paneInsertTable:null,
		paneContextMenu:null,
		tool:null,
		tool2:null,
		dmName:null,
		dmPath:null,
		showTools:true,
		editable:true
	},
	method:{
		construct:function(){
			var v=this.$V,col,img;
			if(!this.$P.defaultStyle)this.$P.defaultStyle=xlv.obj.richEditor.pub.defaultStyle;
			if(!this.$P.paneSelectFont)this.$P.paneSelectFont=xlv.obj.richEditor.pub.paneSelectFont;
			if(!this.$P.paneSelectSize)this.$P.paneSelectSize=xlv.obj.richEditor.pub.paneSelectSize;
			if(!this.$P.paneSelectHead)this.$P.paneSelectHead=xlv.obj.richEditor.pub.paneSelectHead;
			if(!this.$P.paneSelectForeColor)this.$P.paneSelectForeColor=xlv.obj.richEditor.pub.paneSelectForeColor;
			if(!this.$P.paneSelectBackColor)this.$P.paneSelectBackColor=xlv.obj.richEditor.pub.paneSelectBackColor;
			if(!this.$P.paneInsertImage)this.$P.paneInsertImage=xlv.obj.richEditor.pub.paneInsertImage;
			if(!this.$P.paneInsertLink)this.$P.paneInsertLink=xlv.obj.richEditor.pub.paneInsertLink;
			if(!this.$P.paneInsertTable)this.$P.paneInsertTable=xlv.obj.richEditor.pub.paneInsertTable;
			if(!this.$P.paneContextMenu)this.$P.paneContextMenu=xlv.obj.richEditor.pub.paneContextMenu;
			if(!this.$P.tool)this.$P.tool=xlv.obj.richEditor.pub.tool;
			if(!this.$P.tool2)this.$P.tool2=xlv.obj.richEditor.pub.tool2;
			Element.addClassName(this,'class_richEditor');
			v.table=document.createElement('table');
			v.table.setAttribute('id','xlvid_richeditor_table');
			v.table.setAttribute('cellpadding','0');
			v.table.setAttribute('cellspacing','0');
			v.table.appendChild(v.tbody=document.createElement('tbody'));
			v.tbody.setAttribute('id','xlvid_richeditor_tbody');
			v.tbody.appendChild(v.tool=document.createElement('tr'));
			v.tool.setAttribute('id','xlvid_richeditor_tool');
			this._createTool(this.$P.tool,v.tool);
			v.tbody.appendChild(v.tool2=document.createElement('tr'));
			v.tool2.setAttribute('id','xlvid_richeditor_tool');
			this._createTool(this.$P.tool2,v.tool2);
			//
			v.tbody.appendChild(v.content=document.createElement('tr'));
			v.content.setAttribute('id','xlvid_richeditor_content');
			//
			v.content.appendChild(col=document.createElement('td'));
			col.setAttribute('valign','top');
			col.innerHTML='<iframe frameborder="0" src="javascript:void(0);" id="xlvid_richeditor_iframe"></iframe>';
			v.iframe=xlv.util.findChild(col,{tag:'iframe'});
			//
			v.tbody.appendChild(v.status=document.createElement('tr'));
			v.status.setAttribute('id','xlvid_richeditor_status');
			//
			this.styleForId(v.table,v.table.id);
			this.styleForId(v.tbody,v.tbody.id);
			this.styleForId(v.tool,v.tool.id);
			this.styleForId(v.tool2,v.tool2.id);
			this.styleForId(v.content,v.content.id);
			this.styleForId(v.iframe,v.iframe.id);
			this.styleForId(v.status,v.status.id);
			this.appendChild(v.table);
			v.editor=v.iframe;

		},
		styleForId:function(facilities,id){
		},
		initial:function(){
			var v=this.$V,p=this.$P;
			v.window=v.iframe.contentWindow;
			v.document=v.window.document;
			v.document.open();
			v.document.close();
			this.addEventHandler('focus', '_iframe_focus',v.window);
			v.tool.style.display='none';
			v.tool2.style.display='none';
			v.textMode=true;
			v.tool.style.display=(p.showTools&&p.editable)?'':'none';
			v.tool2.style.display=(p.showTools&&p.editable)?'':'none';
		},
		enabled:function(enabled){
			var v=this.$V;
			if(v.enabled==enabled) return;
			v.enabled=enabled;
			this.$V.tool.style.display=(enabled)?'':'none';
			this.$V.tool2.style.display=(enabled)?'':'none';
			if(enabled){
				if(v.document.body.contentEditable)	v.document.body.contentEditable=true;
				else v.document.designMode='on';
				Element.setStyle(v.document.body, this.$P.defaultStyle);
				this.addEventHandler('mousedown', '_toolMouseDown',v.tool);
				this.addEventHandler('mousedown', '_toolMouseDown',v.tool2);
				this.addEventHandler('mousedown', '_iframe_document_mousedown',v.document);
				this.addEventHandler('contextmenu', '_iframe_document_contextmenu',v.document);
				if(Prototype.Browser.IE) this.addEventHandler('keypress', '_invertIELineBreakCapability',v.document);
				this._refreshTableHighlighting();
			}else{
				if(v.document.body.contentEditable) v.document.body.contentEditable=false;
				else v.document.designMode='';	
				this.removeObserve('mousedown','_toolMouseDown',v.tool);
				this.removeObserve('mousedown','_toolMouseDown',v.tool2);
				this.removeObserve('mousedown','_iframe_document_mousedown',v.document);
				this.removeObserve('contextmenu', '_iframe_document_contextmenu',v.document);
				this._hideTools(true);
				if(Prototype.Browser.IE) {
					this.removeObserve('keypress', '_invertIELineBreakCapability',v.document);
				}
				this._disableTableHighlighting();
				if(!Prototype.Browser.IE)v.window.blur();
			}
		},
		commit:function(){
			this.enabled(false);
			var dm=this.mvc_getModel();
			if(dm)this.mvc_valueToModel(this.mvc_valueFromView(),dm);
		},
		_iframe_focus:function(event){
			if(this.$P.editable) this.enabled(true);
		},
		_iframe_document_mousedown:function(event){
			this._hideTools(false);
		},
		_hideTools:function(remove_pane){
		},
		_enableTools:function(enable){
			var v=this.$V;
			var children=xlv.util.children(v.tool,{tag:'div'},null);
			for(var i=0;i<children.length;++i)Element[(enable)?'removeClassName':'addClassName'](children[i],'disabled');
			children=xlv.util.children(v.tool2,{tag:'div'},null);
			for(var i=0;i<children.length;++i)Element[(enable)?'removeClassName':'addClassName'](children[i],'disabled');
			if(v.viewSource)Element.removeClassName(v.viewSource,'disabled');
		},
		_createTool:function(tool_desc,tr){
			var v=this.$V,col,div;
			tr.appendChild(col=document.createElement('td'));
			for(var i=0;i<tool_desc.length;++i){
				if(tool_desc[i].id=='xlvid_richeditor_font') div=this._selectFontTool();
				else if(tool_desc[i].id=='xlvid_richeditor_fontsize') div=this._selectSizeTool();
				else if(tool_desc[i].id=='xlvid_richeditor_headings') div=this._selectHeadTool();
				else if(tool_desc[i].id=='xlvid_richeditor_forecolor') div=this._selectForeColorTool();
				else if(tool_desc[i].id=='xlvid_richeditor_backcolor') div=this._selectBackColorTool();
				else if(tool_desc[i].id=='xlvid_richeditor_insertimage') div=this._insertImageTool();
				else if(tool_desc[i].id=='xlvid_richeditor_insertlink')div=this._insertLinkTool();
				else if(tool_desc[i].id=='xlvid_richeditor_inserttable')div=this._insertTableTool();
				else div=document.createElement('div');
				col.appendChild(div);
				div.setAttribute('id',tool_desc[i].id);
				div.setAttribute('title',tool_desc[i].title);
				div.setAttribute('unselectable', 'on');
				div.cmd=tool_desc[i].cmd;
				if(tool_desc[i].id=='xlvid_richeditor_viewSource')v.viewSource=div;
			}
		},
		_toolMouseDown:function(event){
			var v=this.$V;
			if(Element.hasClassName(event.target,'disabled'))return;
			var id=event.target.id;
			var cmd=event.target.cmd||'';
			var value=null;
			var options={};
			switch(cmd) {
			case 'FontName':
			case 'FontSize':
			case 'FormatBlock'://head
			case 'ForeColor':
			case 'BackColor':
			case 'InsertImage': 
			case 'InsertLink': 
			case 'InsertTable': 
			case 'RemoveImage': 
			case 'RemoveLink': 
			case 'RemoveNode': 
				break;
			case 'ViewMode':
				if(v.textMode) this.sourceMode();
				else this.textMode();
				break;
			case "Print":
				this._print();
				break;
			case "Save":
				this.commit();
				break;
			case "Return":
			case "Help":
			case "RemoveFormat":
				break;
			default: 
				if(cmd && cmd!='')this._execCommand(cmd, value);
			}
		},
		textMode:function(){
			var v=this.$V;
			if(v.textMode) return;
			v.textMode=true;
			if(v.viewSource)v.viewSource.id='xlvid_richeditor_viewSource';
			this._viewText();
		},
		sourceMode:function(){
			var v=this.$V;
			if(!v.textMode) return;
			v.textMode=false;
			if(v.viewSource)v.viewSource.id='xlvid_richeditor_viewText';
			this._viewSource();
		},
		_execCommand: function(cmd, value) {
			var v=this.$V;
			this.$V.window.focus();
			if(typeof(value) == 'undefined') value = null;
			if(cmd == 'BackColor'&&!Prototype.Browser.IE && !Prototype.Browser.Opera) cmd='HiliteColor';
			if(!Prototype.Browser.IE && !Prototype.Browser.Opera&&(cmd=='Cut'||cmd == 'Paste'||cmd == 'Copy')) {
				try {
					v.document.execCommand(cmd, false, value);
				}catch(e) {
					if(confirm('Copy/Cut/Paste is not available in Mozilla and Firefox\nDo you want more information about this issue?')) 
						window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html');
				}
			}else v.document.execCommand(cmd, false, value);
		},
		_selectFontTool:function(){
			var sel_font=document.createElement('div');
			sel_font.setAttribute('xlvobject', 'xlv.obj.process');
			xlv.sys.extend(sel_font);
			var editor=this;
			sel_font.process=function(){
				if(Prototype.Browser.IE) editor.$V.__range=editor._getRange(editor._getSelection());
				var param={value:'',commit:false};
				var options={invoker:sel_font,align:'center'};
				var ajax=sel_font.getDesktop().showPane(editor.$P.paneSelectFont,{caller:param},null,options);
				ajax.dispose=function(){
					try{
						if(param.commit)editor._selectFont(param);
					}catch(e){}
				};
			};
			return this.$V.selectFont=sel_font;
		},
		_selectFont:function(param){
			this.$V.window.focus();
			if(this.$V.__range)	this.$V.__range.select();
			this._execCommand(this.$V.selectFont.cmd,param.value);
		},
		_selectSizeTool:function(){
			var sel_size=document.createElement('div');
			sel_size.setAttribute('xlvobject', 'xlv.obj.process');
			xlv.sys.extend(sel_size);
			var editor=this;
			sel_size.process=function(){
				if(Prototype.Browser.IE) editor.$V.__range=editor._getRange(editor._getSelection());
				var param={value:'',commit:false};
				var options={invoker:sel_size,align:'center'};
				var ajax=sel_size.getDesktop().showPane(editor.$P.paneSelectSize,{caller:param},null,options);
				ajax.dispose=function(){
					try{
						if(param.commit)editor._selectSize(param);
					}catch(e){}
				};

			};
			return this.$V.selectSize=sel_size;
		},
		_selectSize:function(param){
			this.$V.window.focus();
			if(this.$V.__range)	this.$V.__range.select();
			this._execCommand(this.$V.selectSize.cmd,param.value);
		},
		_selectHeadTool:function(){
			var sel_head=document.createElement('div');
			sel_head.setAttribute('xlvobject', 'xlv.obj.process');
			xlv.sys.extend(sel_head);
			var editor=this;
			sel_head.process=function(){
				if(Prototype.Browser.IE) editor.$V.__range=editor._getRange(editor._getSelection());
				var param={value:'',commit:false};
				var options={invoker:sel_head,align:'center'};
				var ajax=sel_head.getDesktop().showPane(editor.$P.paneSelectHead,{caller:param},null,options);
				ajax.dispose=function(){
					try{
						if(param.commit)editor._selectHead(param);
					}catch(e){}
				};
			};
			return this.$V.selectHead=sel_head;
		},
		_selectHead:function(param){
			this.$V.window.focus();
			if(this.$V.__range)	this.$V.__range.select();
			this._execCommand(this.$V.selectHead.cmd,'<'+param.value+'>');
		},
		_selectForeColorTool:function(){
			var sel_fcolor=document.createElement('div');
			sel_fcolor.setAttribute('xlvobject', 'xlv.obj.process');
			xlv.sys.extend(sel_fcolor);
			var editor=this;
			sel_fcolor.process=function(){
				if(Prototype.Browser.IE) editor.$V.__range=editor._getRange(editor._getSelection());
				var param={value:'',commit:false};
				var options={invoker:sel_fcolor,align:'center'};
				var ajax=sel_fcolor.getDesktop().showPane(editor.$P.paneSelectForeColor,{caller:param},null,options);
				ajax.dispose=function(){
					try{
						if(param.commit)editor._selectForeColor(param);
					}catch(e){}
				};
			};
			return this.$V.selectForeColor=sel_fcolor;
		},
		_selectForeColor:function(param){
			this.$V.window.focus();
			if(this.$V.__range)	this.$V.__range.select();
			this._execCommand(this.$V.selectForeColor.cmd,param.value);
		},
		_selectBackColorTool:function(){
			var sel_bcolor=document.createElement('div');
			sel_bcolor.setAttribute('xlvobject', 'xlv.obj.process');
			xlv.sys.extend(sel_bcolor);
			var editor=this;
			sel_bcolor.process=function(){
				if(Prototype.Browser.IE) editor.$V.__range=editor._getRange(editor._getSelection());
				var param={value:'',commit:false};
				var options={invoker:sel_bcolor,align:'center'};
				var ajax=sel_bcolor.getDesktop().showPane(editor.$P.paneSelectBackColor,{caller:param},null,options);
				ajax.dispose=function(){
					try{
						if(param.commit)editor._selectBackColor(param);
					}catch(e){}
				};
			};
			return this.$V.selectBackColor=sel_bcolor;
		},
		_selectBackColor:function(param){
			this.$V.window.focus();
			if(this.$V.__range)	this.$V.__range.select();
			this._execCommand(this.$V.selectBackColor.cmd,param.value);
		},
		_insertImageTool:function(){
			var ins_image=document.createElement('div');
			ins_image.setAttribute('xlvobject', 'xlv.obj.process');
			xlv.sys.extend(ins_image);
			var editor=this;
			ins_image.process=function(){
				if(Prototype.Browser.IE) editor.$V.__range=editor._getRange(editor._getSelection());
				var param={src:'',alt:'',width:'',height:'',border:null,align:'',hspace:'',vspace:'',commit:false};
				var options={invoker:ins_image,align:'center'};
				var ajax=ins_image.getDesktop().showPane(editor.$P.paneInsertImage,{caller:param},null,options);
				ajax.dispose=function(){
					try{
						if(param.commit)editor._insertImage(param);
					}catch(e){}
				};
			};
			return this.$V.insertImage=ins_image;
		},
		_insertImage:function(param){
			this.$V.window.focus();
			if(this.$V.__range)	this.$V.__range.select();
			var doc = this.$V.document;
			var range= this._getRange(this._getSelection());
			var img = this._findParent("img", range);
			var update=(img == null)? false : true;
			if(!update) img = doc.createElement("img");
			if(param.src.strip()=='')return;
			img.setAttribute('src', param.src);
			if(param.width.strip()!='')Element.setStyle(img,{width:param.width});
			if(param.height.strip()!='')Element.setStyle(img,{height:param.height});
			if(param.align.strip()!='') img.setAttribute('align',param.align);
			else img.removeAttribute('align');
			if(param.border != null) img.setAttribute('border',param.border);
			if(param.alt.strip()!='') img.setAttribute('alt',param.alt);
			if(param.hspace.strip()!='') img.setAttribute('hspace',param.hspace);
			if(param.vspace.strip()!='') img.setAttribute('vspace',param.vspace);
			img.removeAttribute('width');
			img.removeAttribute('height');
			if(!update){
				if(Prototype.Browser.IE) range.pasteHTML(img.outerHTML);   
				else this._insertNodeAtSelection(img);
			}
		},
		_insertLinkTool:function(){
			var ins_link=document.createElement('div');
			ins_link.setAttribute('xlvobject', 'xlv.obj.process');
			xlv.sys.extend(ins_link);
			var editor=this;
			ins_link.process=function(){
				var param={linkHref:'',linkTarget:'',linkStyle:'',linkClass:'',linkName:'',commit:false};
				var sel = editor._getSelection();
				var range=editor._getRange(sel);
				if(Prototype.Browser.IE) {
					editor.$V.__range=range;
					if(sel.type == 'Control' && range.length == 1) {	
						range=this._getTextRange(range(0));
						range.select();
					}
				}
				var link = editor._findParent('a', range);
				param.linkHref=(link)?Element.readAttribute(link,'href'):'';
				param.linkClass=(link)?Element.readAttribute(link,'class'):'';
				param.linkTarget=(link)?Element.readAttribute(link,'target'):'';
				param.linkStyle=(link)?Element.readAttribute(link,'style'):'';
				param.linkName=(link)?Element.readAttribute(link,'name'):'';
				if(!sel||!range){
					alert('focus and select a element');
					return;
				}
				var options={invoker:ins_link,align:'center'};
				var ajax=ins_link.getDesktop().showPane(editor.$P.paneInsertLink,{caller:param},null,options);
				ajax.dispose=function(){
					try{
						if(param.commit)editor._insertLink(param);
					}catch(e){}
				};
			};
			return this.$V.insertLink=ins_link;
		},
		_insertLink:function(param){
			this.$V.window.focus();
			if(this.$V.__range)	this.$V.__range.select();
			var doc = this.$V.document;
			var sel = this._getSelection();
			var range = this._getRange(sel);
			if(Prototype.Browser.IE) {
				if(sel.type == 'Control' && range.length == 1) {
					range = this._getTextRange(range(0));
					range.select();
					}
			}
			var link = this._findParent('a', range);
			var update=(link == null)? false : true;
			if(!update) link = doc.createElement('a');
			if(!param.linkHref || param.linkHref.strip()=='') return;
			link.setAttribute('href',param.linkHref);
			if(param.linkClass&&param.linkClass.strip()!='') link.setAttribute('class',param.linkClass);
			else link.removeAttribute('class');
			if(param.linkClass && param.linkClass.strip()!='') link.setAttribute('className',param.linkClass);
			else link.removeAttribute('className');
			if(param.linkTarget && param.linkTarget.strip()!='') link.setAttribute('target',param.linkTarget);
			else link.removeAttribute('target');
			param.linkName=(param.linkName||'noname');
			if(param.linkName&& param.linkName.strip()!='') link.setAttribute('name',param.linkName);
			else link.removeAttribute('name');
			if(param.linkStyle&& param.linkStyle.strip()!='') link.setAttribute('style',param.linkStyle);
			else link.removeAttribute('style');
			if(!update){
				if(Prototype.Browser.IE) {
					range.select();
					link.innerHTML = range.htmlText;
					range.pasteHTML(link.outerHTML);
				}else {
					var node=range.startContainer;	
					var pos=range.startOffset;
					if(node && node.nodeType!=3)node=node.childNodes[pos];
					if(node && node.tagName)link.appendChild(node);
					else link.innerHTML = sel;
					this._insertNodeAtSelection(link);
				}
			}
		},
		_insertTableTool:function(){
			var ins_table=document.createElement('div');
			ins_table.setAttribute('xlvobject', 'xlv.obj.process');
			xlv.sys.extend(ins_table);
			var editor=this;
			ins_table.process=function(){
				var param={rows:'2',cols:'2',padding:'2',borderWidth:'',borderStyle:'',width:'100',widthUnit:'%',alignment:'',bkColor:'',borderColor:'',borderCollapse:'',commit:false};
				var range=editor._getRange(editor._getSelection());
				if(Prototype.Browser.IE) editor.$V.__range=range;
				var options={invoker:ins_table,align:'center'};
				var ajax=ins_table.getDesktop().showPane(editor.$P.paneInsertTable,{caller:param},null,options);
				ajax.dispose=function(){
					try{
						if(param.commit)editor._insertTable(param);
					}catch(e){}
				};
			};
			return this.$V.insertTable=ins_table;
		},
		_insertTable:function(param){
			this.$V.window.focus();
			if(this.$V.__range)	this.$V.__range.select();
			var doc = this.$V.document;
			var range= this._getRange(this._getSelection());
			var table = this._findParent('table', range);
			var update=(table == null)? false : true;
			update=false;
			if(!update) table = doc.createElement('table');
			var rows=(parseInt(param.rows)||0);cols=(parseInt(param.cols)||0);
			if(rows==0||cols==0) return;
			var tbody,tr,td;
			table.appendChild(tbody=doc.createElement('tbody'));
			table.setAttribute('cellpadding','0');
			table.setAttribute('cellspacing','0');
			var style={};
			if(param.borderCollapse)style.borderCollapse=param.borderCollapse;
			if(param.width)style.width=param.width+param.widthUnit;
			//style.backgroundColor=;
			if(param.alignment) style.alignment=param.alignment;
			Element.setStyle(table,style);
			style={};
			if(param.border)style.border=param.border;
			if(param.borderWidth)style.borderWidth=param.borderWidth;
			//style.borderColor=;
			if(param.padding)style.padding=param.padding;
			for(var i=0;i<rows;++i){
				tbody.appendChild(tr=doc.createElement('tr'));
				for(var c=0;c<cols;++c){
					tr.appendChild(td=doc.createElement('td'));
					td.innerHTML='&nbsp;';
					Element.setStyle(td,style);
				}
			}
			if(!update){
				if(Prototype.Browser.IE) range.pasteHTML(table.outerHTML);   
				else this._insertNodeAtSelection(table);
			}
			this._refreshTableHighlighting();
		},
		_iframe_document_contextmenu:function(event){
			if(!this.$P.editable)return;
			var v=this.$V;
			event.stop();
			if(!v.contextMenu && (v.viewSource==null||v.viewSource.id=='xlvid_richeditor_viewSource')){
				this.getDesktop().systemModal(true,0.01,null,'default',(function(){this._contextMenu_document();}).bind(this));
				var offxy=this.getDesktop().viewportOffset(v.iframe);
				var x=offxy.left+event.clientX;
				var y=offxy.top+event.clientY;
				if(Prototype.Browser.IE) x+=24;
				var menu=document.createElement('div');
				menu.setAttribute('xlvobject', 'xlv.obj.ajaxPane');
				var prop={paneURL:this.$P.paneContextMenu,paneProperties:{},autoRequest:true};
				xlv.sys.extend(menu,prop);
				if(Prototype.Browser.IE) this.$V.__range=this._getRange(this._getSelection());
				Element.setStyle(menu,{position:'absolute',display:'block',left:x+'px',top:y+'px',zIndex:xlv.sys.zIndexSystemModal});
				this.getDesktop().appendChild(menu);
				this.addEventHandler('mousedown', '_contextMenu',menu);
				v.contextMenu=menu;
				xlv.sys.initialize(menu);
			}
		},
		_contextMenu:function(event){
			var v=this.$V;
			var target=event.target;
			if(target != this.$V.contextMenu){
				event.stop();
				var tr=(target.id=='xlvid_menu_item')?target:xlv.util.findParent(target,{id:'xlvid_menu_item'},{object:this.$V.contextMenu});
				if(tr){
					this.$V.window.focus();
					if(this.$V.__range)	this.$V.__range.select();
					var cmd=Element.readAttribute(tr,'value');
					this._contextMenu_document();
					if(cmd=="RemoveNode")this._removeNode();
					else if(cmd=="InsertImage")v.insertImage.process();
					else if(cmd=="InsertLink")v.insertLink.process();
					else this._execCommand(cmd,null);
				}
			}
		},
		_contextMenu_document:function(event){
			this.getDesktop().systemModal(false);
			var v=this.$V;
			if(v.contextMenu){
				this.removeObserve('mousedown', '_contextMenu',v.contextMenu);
				xlv.sys.dispose(v.contextMenu,true);
				v.contextMenu=null;
			}
		},
		_removeNode: function() {
			var range=this._getRange(this._getSelection());
			var tag=this._getTag(range);
			var parent=(tag)?tag.parentNode:null;
			if(tag == null || parent == null)return;
			if(tag.nodeName =='HTML' || tag.nodeName == 'BODY')return;
			var childNodes = new Array();
			for(var i=0; i < tag.childNodes.length;i++)	childNodes[i]=tag.childNodes[i];	
			for(var i=0; i < childNodes.length;i++)	parent.insertBefore(childNodes[i], tag);	
			parent.removeChild(tag);
			if(parent.nodeName == 'A' && !parent.hasChildNodes()) {
				if(parent.parentNode) { parent.parentNode.removeChild(parent); }
			}
		},
		_print: function() {
			var v=this.$V;
			this._disableTableHighlighting();
			if(document.all && navigator.appVersion.substring(22,23)==4) {
				var doc = v.document;
				doc.focus();
				var OLECMDID_PRINT = 6;
				var OLECMDEXECOPT_DONTPROMPTUSER = 2;
				var OLECMDEXECOPT_PROMPTUSER = 1;
				var WebBrowser = '<object id="WebBrowser1" width="0" height="0" classid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></object>';
				doc.body.insertAdjacentHTML('beforeEnd',WebBrowser);
				WebBrowser.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER);
				WebBrowser.outerHTML = '';
			} else 	v.window.print();
			this._refreshTableHighlighting();
		},
		_getRange: function(sel) {
			try{
				return sel.createRange ? sel.createRange() : sel.getRangeAt(0);
			}catch(e){return null;}
		},
		_getSelection:function() {
			var v=this.$V;
			var sel = null;
			if(v.window.getSelection){
				sel = v.window.getSelection();
			}else if(v.document.getSelection) {
				sel = v.document.getSelection();
			}else if(v.document.selection) {
				sel = v.document.selection;
			}
			return sel;
		},
		_invertIELineBreakCapability:function(event) {
			if(event.keyCode==13) {
				var sel=this._getRange(this._getSelection());
				var li=this._findParent('li',sel);
				if(li)return;
				sel.pasteHTML((!event.shiftKey) ?'<br>':'<p>');
	            event.cancelBubble = true;
	            event.returnValue = false;
	            sel.select();
	            sel.moveEnd("character", 1);
	            sel.moveStart("character", 1);
	            sel.collapse(false);
	            return false;
			}  
		},
		_getTag: function(range) {
			try {
			    if(!Prototype.Browser.IE){
					var node = range.startContainer;	
					var pos = range.startOffset;
					if(node.nodeType != 3)node = node.childNodes[pos];
					return (node.nodeName&&node.nodeName.search(/#/)!=-1)?node.parentNode:node;
				}else {
					if(range.length > 0)return range.item(0);
					else if(range.parentElement()) return range.parentElement();
				}
				return null;
			}
			catch(e) {
				return null;
			}
		},
		_findParent: function(parentTagName, range){
			parentTagName = parentTagName.toUpperCase();
			var rangeWorking;
			var elmWorking = null;
			try {
				if(!Prototype.Browser.IE) {
					var node = range.startContainer;	
					var pos = range.startOffset;
					if(node.nodeType != 3) { node = node.childNodes[pos]; }
					return this._findParentNode(parentTagName, node);
				}
				else {
					elmWorking = (range.length > 0) ? range.item(0): range.parentElement();					
					elmWorking = this._findParentNode(parentTagName, elmWorking);
					if(elmWorking != null) return elmWorking;
					rangeWorking = range.duplicate();
					rangeWorking.collapse(true);
					rangeWorking.moveEnd("character", 1);
					if (rangeWorking.text.length>0) {
						while (rangeWorking.compareEndPoints("EndToEnd", range) < 0){
				  			rangeWorking.move("Character");
				  			if (null != this.findParentTag(parentTagName, rangeWorking)){
				   				return this.findParentTag(parentTagName, rangeWorking);
				  			}
				 		}
				 	}
				 	return null;
				}
			}
			catch(e) {
				return null;
			}
		},
		_findParentNode: function(tagName, node) {
			while(node.tagName != 'HTML') {
		  		if(node.tagName == tagName)return node;
		  		node = node.parentNode;
		 	}
		 	return null;
		},
		_getTextRange: function(element){
			var range = element.parentTextEdit.createTextRange();
			range.moveToElementText(element);
			return range;
		},
		_insertNodeAtSelection: function(insertNode) {
			var doc = this.$V.document;
			var sel = this._getSelection();
			var range = sel.getRangeAt(0);
			sel.removeAllRanges();
			range.deleteContents();
			var container = range.startContainer;
			var pos = range.startOffset;
			range = doc.createRange();
			if (container.nodeType==3 && insertNode.nodeType==3) {					
				container.insertData(pos, insertNode.data);
				range.setEnd(container, pos+insertNode.length);
				range.setStart(container, pos+insertNode.length);		
			}else {
				var afterNode;	
				var beforeNode;
				if(container.nodeType==3) {
					var textNode = container;
					container = textNode.parentNode;
					var text = textNode.nodeValue;
					var textBefore = text.substr(0,pos);
					var textAfter = text.substr(pos);
					beforeNode = document.createTextNode(textBefore);
					afterNode = document.createTextNode(textAfter);
					container.insertBefore(afterNode, textNode);
					container.insertBefore(insertNode, afterNode);
					container.insertBefore(beforeNode, insertNode);
					container.removeChild(textNode);
				}else {
					afterNode = container.childNodes[pos];
					container.insertBefore(insertNode, afterNode);
				}
				try {
					if(afterNode){
						range.setEnd(afterNode, 0);
						range.setStart(afterNode, 0);
					}
				}catch(e) {
					alert(e);
				}
			}
			sel.addRange(range);
		},
		_toHexColor: function(color) {
			color = color.replace(/^rgb/g,'');
			color = color.replace(/\(/g,'');
			color = color.replace(/\)/g,'');
			color = color.replace(/ /g,'');
			color = color.split(',');
			var r = parseFloat(color[0]).toString(16).toUpperCase();
			var g = parseFloat(color[1]).toString(16).toUpperCase();
			var b = parseFloat(color[2]).toString(16).toUpperCase();
			if (r.length<2) { r='0'+r; }
			if (g.length<2) { g='0'+g; }
			if (b.length<2) { b='0'+b; }
			return r + g + b;
		},
		_dec_to_rgb: function(value) {
			var hex_string = '';
			for (var hexpair = 0; hexpair < 3; hexpair++) {
				var myByte = value & 0xFF;   
				value >>= 8;                    
				var nybble2 = myByte & 0x0F;    
				var nybble1 = (myByte >> 4) & 0x0F; 
				hex_string += nybble1.toString(16);
				hex_string += nybble2.toString(16);
			}
			return hex_string.toUpperCase();
		},
		_replaceRGBWithHexColor :function(str) {
			if(str == null) return '';
			var matcher = str.match(/rgb\([0-9 ]+,[0-9 ]+,[0-9 ]+\)/gi);
			if(matcher) {
				for(var j=0; j<matcher.length;j++) {
					var regex = eval('/' + this._stringToRegex(matcher[j]) + '/gi');
					str = str.replace(regex, '#' + this._toHexColor(matcher[j]));
				}
			}
			return str;
		},
		_refreshTableHighlighting: function() {
			var doc = this.$V.document;
			var tables = doc.getElementsByTagName('table');	
			for(var i=0;i<tables.length;i++) {
				this._enableHighlighting(tables[i]);
			}
			var tds = doc.getElementsByTagName('td');	
			for(var i=0;i<tds.length;i++) {
				this._enableHighlighting(tds[i]);
			}
		},
		_disableTableHighlighting: function() {
			var doc = this.$V.document;
			var tables = doc.getElementsByTagName('table');	
			for(var i=0;i<tables.length;i++) {
				this._disableHighlighting(tables[i]);
			}
			var tds = doc.getElementsByTagName('td');	
			for(var i=0;i<tds.length;i++) {
				this._disableHighlighting(tds[i]);
			}
		},
		_enableHighlighting: function(node) {
			var style = Element.readAttribute(node, 'style');	
			if(style == null) style=' ';
			node.removeAttribute('prevstyle');
			node.setAttribute('prevstyle', style);
			Element.setStyle(node,{border:'1px dashed #AAAAAA'});
		},
		_disableHighlighting: function(node) {
			var style = Element.readAttribute(node,'prevstyle');
			if(style == null || style == '') { 
				this._enableHighlighting(node); 
				return; 
			}			
			node.removeAttribute('prevstyle');
			node.removeAttribute('style');
			Element.setStyle(node,style);
		},
		_viewSource: function() {
			var doc = this.$V.document;
			this._disableTableHighlighting();
			var html;
			if(Prototype.Browser.IE) {
				html=doc.body.innerHTML;
				html=this._stripURLPath(html);
				html=this._replaceRGBWithHexColor(html);
				doc.body.innerText=html;
			}else {
				html=this._replaceRGBWithHexColor(doc.body.innerHTML);
		    	html=document.createTextNode(html);
		    	doc.body.innerHTML='';
		    	doc.body.appendChild(html);
		  	}
			doc.body.style.fontSize='12px';
			doc.body.style.fontFamily='Courier New'; 
			this._enableTools(false);
	},
	_getDocumentUrl:function() {
		var url = this.$V.document.URL;
		url = url.replace(/file:\/\//gi, 'file:///');
		url = url.replace(/\\/gi, '\/');
		return url;
	},
	_getDocumentPathOfUrl:function(url) {
		var path = null;
		url = url.replace(/file:\/\//gi, 'file:///');
		url = url.replace(/\\/gi, '\/');
		var pos = url.lastIndexOf('/');
		if(pos != -1) path = url.substring(0,pos + 1);
		return path;
	},
	_stringToRegex: function(string) {
		string = string.replace(/\//gi, '\\/');
		string = string.replace(/\(/gi, '\\(');
		string = string.replace(/\)/gi, '\\)');
		string = string.replace(/\[/gi, '\\[');
		string = string.replace(/\]/gi, '\\]');
		string = string.replace(/\+/gi, '\\+');
		string = string.replace(/\$/gi, '\\$');
		string = string.replace(/\*/gi, '\\*');
		string = string.replace(/\?/gi, '\\?');
		string = string.replace(/\^/gi, '\\^');
		string = string.replace(/\\b/gi, '\\\\b');
		string = string.replace(/\\B/gi, '\\\\B');
		string = string.replace(/\\d/gi, '\\\\d');
		string = string.replace(/\\B/gi, '\\\\B');
		string = string.replace(/\\D/gi, '\\\\D');
		string = string.replace(/\\f/gi, '\\\\f');
		string = string.replace(/\\n/gi, '\\\\n');
		string = string.replace(/\\r/gi, '\\\\r');
		string = string.replace(/\\t/gi, '\\\\t');
		string = string.replace(/\\v/gi, '\\\\v');
		string = string.replace(/\\s/gi, '\\\\s');
		string = string.replace(/\\S/gi, '\\\\S');
		string = string.replace(/\\w/gi, '\\\\w');
		string = string.replace(/\\W/gi, '\\\\W');
		return string;			
	},
	_stripURLPath:function(content,exact){
		if(typeof exact == 'undefined')exact=true;
		var stripImgageUrl = this._getDocumentUrl();
		var stripAnchorUrl = this._getDocumentUrl();
		var url;
		var regex;
		var result;
		if(stripImgageUrl) {
			url=this._stringToRegex(this._getDocumentPathOfUrl(stripImgageUrl));	
			if(exact){
				regex = eval('/(src=\")(' + url + ')([^\"]*)/gi');
				content = content.replace(regex, '$1$3');	
			}else{
				regex = eval('/(' + url + ')(.+)/gi');
				content = content.replace(regex,'$2');	
			}
			result=this._getDocumentPathOfUrl(stripImgageUrl).match(/.+[\/]{2,3}[^\/]*/,'');
			if(result){
				url=this._stringToRegex(result[0]);
				if(exact){
					regex = eval('/(src=\")(' + url + ')([^\"]*)/gi');
					content = content.replace(regex,'$1$3');
				}else{
					regex = eval('/(' + url + ')(.+)/gi');
					content = content.replace(regex,'$2');	
				}
			}	
		}
		if(stripAnchorUrl) {						
			url=this._stringToRegex(this._getDocumentPathOfUrl(stripAnchorUrl));
			if(exact){
				regex = eval('/(href=\")(' + url + ')([^\"]*)/gi');
				content = content.replace(regex, '$1$3');	
			}else{
				regex = eval('/(' + url + ')(.+)/gi');
				content = content.replace(regex, '$2');	
			}
			result=this._getDocumentPathOfUrl(stripAnchorUrl).match(/.+[\/]{2,3}[^\/]*/,'');
			if(result){
				url=this._stringToRegex(result[0]);
				if(exact){
					regex = eval('/(href=\")(' + url + ')([^\"]*)/gi');
					content = content.replace(regex, '$1$3');	
				}else {
					regex = eval('/(' + url + ')(.+)/gi');
					content = content.replace(regex,'$2');	
				}
			}
			url=this._stringToRegex(stripAnchorUrl);
			if(exact) {
				regex = eval('/(href=\")(' + url + ')(#[^\"]*)/gi');
				content = content.replace(regex,'$1$3');
			}else{
				regex = eval('/(' + url + ')(.+)/gi');
				content = content.replace(regex,'$2');	
			}
			url=this._getDocumentUrl();
			var pos = url.lastIndexOf('/');
			if(pos != -1) {
				url=url.substring(pos + 1, url.length);
				url=this._stringToRegex(url);
				if(exact) {
					regex = eval('/(href=\")(' + url + ')(#[^\"]*)/gi');
					content = content.replace(regex,'$1$3');
				}else {
					regex = eval('/(' + url + ')(.+)/gi');
					content = content.replace(regex,'$2');	
				}
			}
		}
		return content;
	},
	_viewText: function() { 
		var doc = this.$V.document;
		if(Prototype.Browser.IE) {
	    	var iText = doc.body.innerText;
			iText = this._stripURLPath(iText);
			iText = this._replaceRGBWithHexColor(iText);
	    	doc.body.innerHTML = iText;
		}else{
	    	var html = doc.body.ownerDocument.createRange();
	    	html.selectNodeContents(doc.body);
			html = this._replaceRGBWithHexColor(html.toString());
	    	doc.body.innerHTML = html;
		}
		this._refreshTableHighlighting();
		this._enableTools(true);
	},
	//
	mvc_valueFromModel:function(dm){
		return this.mvc_isModel(dm) ? dm.getValue(this.$P.dmPath) : null;
	},
	mvc_valueToModel:function(value,dm){
		if(this.mvc_isModel(dm)) dm.setValue(value,this.$P.dmPath);
	},
	mvc_beforeModelChanged:function(model,notify,memo){
		if(this.mvc_isModel(model)&& notify=='cursorMove'&& this.editor_editing())
			this._editor_endEdit(true);
	},
	mvc_valueFromView:function(){
		this.textMode();
		var doc = this.$V.document;
		var html=doc.body.innerHTML;
		if(html=='<br>'||html=='<BR>'||html=='<p>&nbsp;</p>'||html=='<P>&nbsp;</P>') html='';
		return html;
	},
	mvc_valueToView:function(value){
		this.textMode();
		var doc = this.$V.document;
		Element.setStyle(doc.body, this.$P.defaultStyle);
		doc.body.innerHTML = value;
	},
	/**editor imp*/
	editor_startEdit:function(){
	},
	editor_valueToEditor:function(value){
		this.mvc_valueToView(value);
	},
	editor_valueFromEditor:function(){
		return this.mvc_valueFromView();
	},
	editor_endEdit:function(commit){
		var dm=this.mvc_getModel();
		if(dm && commit)this.mvc_valueToModel(this.editor_valueFromEditor(),dm);
		if(dm && !commit)this.editor_valueToEditor(this.mvc_valueFromModel(dm));
	}
  }
};
